home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 23
/
AACD 23.iso
/
AACD
/
Programming
/
Wipeout
/
source
/
filter.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-12
|
7KB
|
402 lines
/*
* $Id: filter.c 1.4 1998/04/12 18:06:58 olsen Exp olsen $
*
* :ts=4
*
* Wipeout -- Traces and munges memory and detects memory trashing
*
* Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
* Public Domain
*/
#ifndef _GLOBAL_H
#include "global.h"
#endif /* _GLOBAL_H */
/******************************************************************************/
STATIC struct MinList ForbidList;
STATIC struct MinList PermitList;
STATIC BOOL ListsInitialized;
STATIC BOOL ForbidAll;
STATIC BOOL PermitAll;
/******************************************************************************/
STATIC VOID
ClearList(struct MinList * list)
{
struct MinNode * node;
struct MinNode * next;
/* return the contents of a list to the
* public memory list.
*/
for(node = list->mlh_Head ;
(next = node->mln_Succ) != NULL ;
node = next)
{
PrivateFreeVec(node);
}
/* leave an empty list behind */
NewList((struct List *)list);
}
STATIC VOID
MoveList(struct MinList * source,struct MinList * destination)
{
struct MinNode * node;
struct MinNode * next;
/* move the contents of one list to another */
for(node = source->mlh_Head ;
(next = node->mln_Succ) != NULL ;
node = next)
{
AddTail((struct List *)destination,(struct Node *)node);
}
/* leave an empty source list behind */
NewList((struct List *)source);
}
/******************************************************************************/
VOID
ClearFilterList(VOID)
{
/* clear both filter lists, but only if they
* have been initialized before.
*/
if(ListsInitialized)
{
ClearList(&ForbidList);
ClearList(&PermitList);
}
}
VOID
InitFilterList(VOID)
{
/* initialize the filter lists and assume
* defaults (track all memory allocations)
*/
if(NOT ListsInitialized)
{
NewList((struct List *)&ForbidList);
NewList((struct List *)&PermitList);
ListsInitialized = TRUE;
ForbidAll = FALSE;
PermitAll = TRUE;
}
}
/******************************************************************************/
STATIC BOOL
GetNextName(
STRPTR * keyPtr,
STRPTR name,
LONG nameLen)
{
STRPTR start;
STRPTR stop;
BOOL result = FALSE;
/* scan the "key" string for the next following name;
* names are separated by "|" characters
*/
ASSERT(keyPtr != NULL && name != NULL && nameLen > 0);
start = (*keyPtr);
while((*start) != '\0' && (*start) == '|')
start++;
stop = start;
while((*stop) != '\0')
{
if((*stop) == '\\')
{
if(stop[1] != '\0')
{
stop += 2;
}
else
{
break;
}
}
else
{
if((*stop) == '|')
{
break;
}
else
{
stop++;
}
}
}
if(start != stop)
{
LONG keyLen = (LONG)stop - (LONG)start + 1;
LONG len;
LONG i;
len = 0;
for(i = 0 ; i < keyLen ; i++)
{
if(start[i] == '|' || len == nameLen)
break;
if(start[i] == '\\')
{
name[len++] = start[++i];
}
else
{
name[len++] = start[i];
}
}
name[len] = '\0';
if((*stop) == '|')
{
(*keyPtr) = stop+1;
}
else
{
(*keyPtr) = stop;
}
result = TRUE;
}
/* return TRUE if there is another name to follow,
* FALSE otherwise (= finished processing the key
* string)
*/
return(result);
}
/******************************************************************************/
BOOL
UpdateFilter(const STRPTR filterString)
{
STRPTR string = (STRPTR)filterString;
struct MinList forbidList;
struct MinList permitList;
UBYTE taskName[MAX_FILENAME_LEN];
STRPTR name;
BOOL forbidAll;
BOOL permitAll;
BOOL success = TRUE;
/* assume defaults */
NewList((struct List *)&forbidList);
NewList((struct List *)&permitList);
forbidAll = FALSE;
permitAll = TRUE;
/* process the filter string */
while(GetNextName(&string,taskName,sizeof(taskName)))
{
/* exclude a name from the list? */
if(taskName[0] == '!')
{
name = &taskName[1];
/* "ALL" means that no allocation should be
* excluded from being watched
*/
if(Stricmp(name,"ALL") == SAME)
{
forbidAll = TRUE;
ClearList(&forbidList);
}
else
{
struct Node * node;
/* remember the name of the task whose name
* should be used in the exclusion list
*/
node = PrivateAllocVec(sizeof(*node) + strlen(name)+1,MEMF_ANY);
if(node != NULL)
{
node->ln_Name = (char *)(node + 1);
strcpy(node->ln_Name,name);
AddTail((struct List *)&forbidList,node);
forbidAll = FALSE;
}
else
{
success = FAILURE;
break;
}
}
}
else
{
name = taskName;
/* "ALL" means that all allocations should be
* watched
*/
if(Stricmp(name,"ALL") == SAME)
{
permitAll = TRUE;
ClearList(&permitList);
}
else
{
struct Node * node;
/* remember the name of the task whose name
* should be used in the inclusion list
*/
node = PrivateAllocVec(sizeof(*node) + strlen(name)+1,MEMF_ANY);
if(node != NULL)
{
node->ln_Name = (char *)(node + 1);
strcpy(node->ln_Name,name);
AddTail((struct List *)&permitList,node);
permitAll = FALSE;
}
else
{
success = FAILURE;
break;
}
}
}
}
/* did we succeed in splitting the filter string
* into list nodes?
*/
if(success)
{
Forbid();
/* get rid of all the old filter list entries */
ClearList(&ForbidList);
ClearList(&PermitList);
/* use the new list entries */
MoveList(&forbidList,&ForbidList);
MoveList(&permitList,&PermitList);
/* and the new options */
ForbidAll = forbidAll;
PermitAll = permitAll;
Permit();
}
else
{
ClearList(&forbidList);
ClearList(&permitList);
}
return(success);
}
/******************************************************************************/
BOOL
CanAllocate(VOID)
{
BOOL result = TRUE;
/* check whether the current task should be allowed to
* make a memory allocation to be watched
*/
if(GetTaskName(NULL,GlobalNameBuffer,sizeof(GlobalNameBuffer)))
{
if(ForbidAll)
{
/* should the allocations not be watched? */
if(CANNOT FindIName((struct List *)&PermitList,GlobalNameBuffer))
result = FALSE;
}
else if (PermitAll)
{
/* should the allocations not be watched? */
if(FindIName((struct List *)&ForbidList,GlobalNameBuffer))
result = FALSE;
}
else
{
result = FALSE;
/* should the allocations be watched? */
if( FindIName((struct List *)&PermitList,GlobalNameBuffer) &&
CANNOT FindIName((struct List *)&ForbidList,GlobalNameBuffer))
{
result = TRUE;
}
}
}
return(result);
}
/******************************************************************************/
VOID
CheckFilter(VOID)
{
/* print the contents of the two watch lists */
Forbid();
if(NOT IsListEmpty((struct List *)&PermitList))
{
struct Node * node;
DPrintf("\nMemory allocations done by the following task(s) are being watched:\n");
for(node = (struct Node *)PermitList.mlh_Head ;
node->ln_Succ != NULL ;
node = node->ln_Succ)
{
DPrintf("\t\"%s\"\n",node->ln_Name);
}
}
if(NOT IsListEmpty((struct List *)&ForbidList))
{
struct Node * node;
DPrintf("\nMemory allocations done by the following task(s) are NOT being watched:\n");
for(node = (struct Node *)ForbidList.mlh_Head ;
node->ln_Succ != NULL ;
node = node->ln_Succ)
{
DPrintf("\t\"%s\"\n",node->ln_Name);
}
}
Permit();
}